package com.rtsapp.server.utils;


import com.rtsapp.server.logger.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by admin on 16/8/11.
 */
public class CheckMoney {
    private static final Logger LOGGER = com.rtsapp.server.logger.LoggerFactory.getLogger(CheckMoney.class);

    private static CheckMoney checkMoney = new CheckMoney();
    //物品或货币ID,玩家ID,当天增长的值
    private Map<Integer, Map<Integer, AtomicInteger>> allPlayerMoneyOrProps = new ConcurrentHashMap<>();
    private long startTime;
    //物品或者货币ID,阀值
    private Map<Integer, Integer> checkNumMap = new HashMap<>();
    private CheckMoneyHandler checkMoneyHandler = null;
    private String configFilePath = null;

    public static CheckMoney getInstance() {
        return CheckMoney.checkMoney;
    }

    public void init(CheckMoneyHandler checkMoneyHandler, String configPath) {
        this.checkMoneyHandler = checkMoneyHandler;
        this.configFilePath = configPath;
        readFile();
    }

    public void readFile() {
        File flie = new File(configFilePath);
        SAXReader saxReader = new SAXReader();
        Document dom;
        try {
            dom = saxReader.read(flie);
        } catch (DocumentException e) {
            e.printStackTrace();
            LOGGER.debug(e.getMessage());
            return;
        }

        Element root = dom.getRootElement();
        String aSwitch = root.element("switch").attributeValue("value"); //开关
        if ("false".equals(aSwitch)) {
            return;
        }
        String isWhiteList = root.element("model").attributeValue("isWhiteList");//是否是白名单
        String[] playerIds = root.element("model").getTextTrim().split(" ");
        if ("false".equals(isWhiteList)) {
            for (String playerId : playerIds) {
                for (Map map : allPlayerMoneyOrProps.values()) {
                    if (map.get(Integer.valueOf(playerId)) != null) {
                        map.put(Integer.valueOf(playerId), map.get(Integer.valueOf(playerId)));
                    } else {
                        map.put(Integer.valueOf(playerId), 0);
                    }
                }
            }
        } else {
            for (String playerId : playerIds) {
                for (Map map : allPlayerMoneyOrProps.values()) {
                    if (map.keySet().contains(Integer.valueOf(playerId))) {
                        map.remove(Integer.valueOf(playerId));
                    }
                }
            }
        }

        List<Element> thresholds = root.element("thresholds").elements();
        for (Element element : thresholds) {
            checkNumMap.put(Integer.parseInt(element.attribute("id").getValue()), Integer.parseInt(element.attribute("value").getValue()));
        }

    }

    public void checkMoneyOrProp(int playerId, int dictId, int changeNum) {

        if (changeNum <= 0) {
            return;
        }

        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        if (startTime < calendar.getTimeInMillis()) {
            allPlayerMoneyOrProps.clear();
            startTime = calendar.getTimeInMillis();
        }

        Map<Integer, AtomicInteger> playerMoneyOrProps = null;
        if (allPlayerMoneyOrProps.containsKey(dictId)) {
            playerMoneyOrProps = allPlayerMoneyOrProps.get(dictId);
        }
        if (playerMoneyOrProps == null) {
            Map<Integer, AtomicInteger> tmpPlayerMoneyOrProps = new ConcurrentHashMap<>();
            playerMoneyOrProps = allPlayerMoneyOrProps.putIfAbsent(dictId, tmpPlayerMoneyOrProps);
            if (playerMoneyOrProps == null) {
                playerMoneyOrProps = tmpPlayerMoneyOrProps;
            }
        }

        AtomicInteger playerMoneyOrProp = null;
        if (playerMoneyOrProps.containsKey(playerId)) {
            playerMoneyOrProp = playerMoneyOrProps.get(playerId);
        }
        if (playerMoneyOrProp == null) {

            AtomicInteger tmpPlayerMoneyOrProp = new AtomicInteger(0);
            playerMoneyOrProp = playerMoneyOrProps.putIfAbsent(playerId, tmpPlayerMoneyOrProp);
            if (playerMoneyOrProp == null) {
                playerMoneyOrProp = tmpPlayerMoneyOrProp;
            }
        }
        int currentAddNum = playerMoneyOrProp.addAndGet(changeNum);

        int checkNum = Integer.MAX_VALUE;
        if (checkNumMap.containsKey(dictId)) {
            checkNum = checkNumMap.get(dictId);
        } else if (checkNumMap.containsKey(0)) {
            checkNum = checkNumMap.get(0);
        }

        if (currentAddNum >= checkNum && checkMoneyHandler != null) {
            this.checkMoneyHandler.run(playerId, dictId, changeNum);
        }


    }

    public interface CheckMoneyHandler {
        void run(int playerId, int dictId, int changeNum);
    }


}
